<template>
  <el-dialog
    :model-value="dialogVisible"
    :title="title"
    @close="handleCancel"
    destroy-on-close
  >
    <!-- 表单区块 -->
    <el-form label-width="100" :rules="rules" :model="ruleForm" ref="formRef">
      <el-row>
        <el-col :span="12">
          <el-form-item label="站点名称:" prop="name">
            <el-input v-model="ruleForm.name" />
          </el-form-item>
          <el-form-item label="站点ID:" prop="id">
            <el-input v-model="ruleForm.id" :disabled="disabled" />
          </el-form-item>
          <el-form-item label="所属城市:" prop="city">
            <el-input v-model="ruleForm.city" />
          </el-form-item>
          <el-form-item label="站点负责人:" prop="person">
            <el-input v-model="ruleForm.person" />
          </el-form-item>
          <el-form-item label="负责人电话:" prop="tel">
            <el-input v-model="ruleForm.tel" />
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="快充数:" prop="fast">
            <el-input v-model="ruleForm.fast" />
          </el-form-item>
          <el-form-item label="慢充数:" prop="slow">
            <el-input v-model="ruleForm.slow" />
          </el-form-item>
          <el-form-item label="充电站状态:" prop="status">
            <el-select
              placeholder="请选择充电站状态"
              v-model="ruleForm.status"
              :disabled="disabled"
            >
              <el-option label="全部" :value="1" />
              <el-option label="使用中" :value="2" />
              <el-option label="空闲中" :value="3" />
              <el-option label="维护中" :value="4" />
              <el-option label="待维修" :value="5" />
            </el-select>
          </el-form-item>
          <el-form-item label="正在充电:" prop="now">
            <el-input v-model="ruleForm.now" :disabled="disabled" />
          </el-form-item>
          <el-form-item label="故障数量:" prop="fault">
            <el-input v-model="ruleForm.fault" :disabled="disabled" />
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel()">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确认 </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { reactive, ref, watch } from "vue";

/**
 * 功能作用: 跟父组件进行数据的双向绑定交互,并且进行表单数据的校验
 * 功能描述:
 * 引入 Rowtype 类型定义,用于定义表单数据的类型
 * 引入 element-plus 的 FormRules 类型,用于定义表单校验规则
 * 使用 ref 定义一个响应式的 ruleForm 对象,用于双向绑定表单数据,并且在 html 中使用 :model 进行双向绑定
 * 使用 reactive 定义一个响应式的 rules 对象,用于定义表单校验规则
 */
// 充电站管理-类型定义
import type { RowType } from "@/types/station/index";
//引入 element 里的校验
import type { FormRules } from "element-plus";

// 定义双向绑定的表单数据
const ruleForm = ref<RowType>({
  name: "",
  id: "",
  city: "",
  fast: "",
  slow: "",
  status: 1,
  now: "",
  fault: "",
  person: "",
  tel: "",
});

// 创建表单校验规则
const rules = reactive<FormRules<RowType>>({
  name: [{ required: true, message: "请输入站点名称", trigger: "blur" }],
  id: [{ required: true, message: "请输入站点ID", trigger: "blur" }],
  city: [{ required: true, message: "请输入所属城市", trigger: "blur" }],
  fast: [{ required: true, message: "请输入快充数", trigger: "blur" }],
  slow: [{ required: true, message: "请输入慢充数", trigger: "blur" }],
  status: [{ required: true, message: "请选择充电站状态", trigger: "change" }],
  now: [{ required: true, message: "请输入正在充电", trigger: "blur" }],
  fault: [{ required: true, message: "请输入故障数量", trigger: "blur" }],
  person: [{ required: true, message: "请输入站点负责人", trigger: "blur" }],
  tel: [{ required: true, message: "请输入负责人电话", trigger: "blur" }],
});

/**
 * 功能作用: 控制组件的显示和隐藏
 * 功能描述:
 * 使用 defineProps 定义一个 dialogVisible 属性,用于控制组件的显示和隐藏
 * 使用 defineEmits 定义一个 close 事件,用于触发父组件的事件
 * 创建 handleCancel 方法,用于取消按钮的事件处理
 * 在 handleCancel 方法中,清空表单数据,并触发父组件的事件,关闭对话框
 */

// 从父组件接收参数,用于控制组件 显示隐藏
const props = defineProps<{
  dialogVisible: boolean;
}>();

// 取消按钮事件
const emit = defineEmits(["close", "reload"]);
const handleCancel = () => {
  // 清空表单数据
  ruleForm.value = {
    name: "",
    id: "",
    city: "",
    fast: "",
    slow: "",
    status: 1,
    now: "",
    fault: "",
    person: "",
    tel: "",
  };
  // 触发父组件的事件，关闭对话框
  emit("close");
};

/**
 * 功能作用: 结合 pinia 实现编辑功能,同时判断是当前是新增还是编辑
 * 功能描述:
 * 1:引入 pinia 中的 useStationStore,用于获取和设置当前行数据
 * 2:声明 stationStore 变量,解构赋值 useStationStore 用于访问 pinia 中的 store
 * 3:从 pinia 里获取 storeToRefs 方法,用于获取 pinia 中的响应式数据
 * 4:从 pinia store 中获取 rowData 方法,用于设置当前行数据, 注意: stationStore 要用 storeToRefs 来获取响应式数据
 * 5:声明 disabled 变量,用于控制表单的禁用状态
 * 6:声明 watch 方法,监听 props.dialogVisible(控制组件是否显示的变量) 的变化
 * 6-1:如果 rowData(pinia 里的当前行数据) 有值, 代表当前是编辑操作,设置 title 为 "编辑充电站信息",并禁用 ID 输入框
 * 6-2:如果 rowData(pinia 里的当前行数据) 没有值, 代表当前是新增操作,设置 title 为 "新增充电站信息",并不禁用 ID 输入框
 * 7:不管是编辑还是新增, 都将 rowData(pinia 里的当前行数据) 的值赋给 ruleForm(表单双向绑定的数据)
 */
import { useStationStore } from "@/store/station";
const stationStore = useStationStore();
import { storeToRefs } from "pinia";
const { rowData } = storeToRefs(stationStore); // 拿到 pinia store 中的 rowData(数据)
// 控制表单禁用状态
const disabled = ref<boolean>(false);
// 定义动态组件标题
const title = ref<string>("");
// 监听显示对话框的变化,如果组件显示,则将 rowData 的值赋给 ruleForm(表单双向绑定的数据)
watch(
  () => props.dialogVisible, // 监听源
  () =>
    // 回调函数 当 props.dialogVisible 变化时执行
    {
      // 如果 rowData(pinia 里的当前行数据) 有值, 代表当前是编辑操作
      if (rowData.value.name) {
        title.value = "编辑充电站信息";
        disabled.value = true; // 显示时禁用 ID 输入框
      }
      // 如果 rowData(pinia 里的当前行数据) 没有值, 代表当前是新增操作
      else {
        title.value = "新增充电站信息";
        disabled.value = false; // 新增时不禁用  ID 输入框
      }
      // 不管是编辑还是新增, 都将 rowData(pinia 里的当前行数据) 的值赋给 ruleForm(表单双向绑定的数据)
      ruleForm.value = { ...rowData.value };
    }
);

/**
 * 功能作用: 组件的确定按钮事件处理
 * 功能描述:
 * 1:引入 element-plus 的 ElMessage 组件,用于提示操作结果
 * 2:引入 editApi 方法,用于调用编辑接口
 * 3:定义 formRef 变量,用于获取表单的引用,让你能够：直接访问表单组件实例,调用表单的内置方法（如验证、重置等）,操作表单的 DOM 元素
 * 4:创建 handleConfirm 方法,用于处理确定按钮的点击事件
 * 4.1: 在 handleConfirm 方法中,使用 formRef.value?.validate 方法进行表单验证 .validate 作用是提交前验证整个表单
 * 4.2: 如果表单验证通过(valid 为 true),先声明 res 变量,调用 editApi 方法,传入 ruleForm.value(表单数据)进行编辑操作
 * 4.3: 如果 res.code === 200,表示操作成功,使用 ElMessage.success 提示操作成功,并调用 handleCancel 方法关闭对话框 ,同时触发父组件的 reload 事件,重新加载数据
 * 4.4: 如果表单验证不通过(valid 为 false),声明 fields 变量,打印表单验证失败的日志,并获取详细的验证错误信息, getFieldsError() 是 Element Plus 表单组件中用于获取详细验证错误信息的方法
 * 注意: 在调用 API 时,需要使用 async/await 语法来处理异步请求,这样可以确保在请求完成后再进行后续操作,避免回调地狱和错误处理的复杂性
 */

// 确认按钮事件
import { ElMessage } from "element-plus";
import { editApi } from "@/api/chargingstation.ts";
const formRef = ref();
const handleConfirm = () => {
  formRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      try {
        const res = await editApi(ruleForm.value); // 调用编辑 API
        if (res.code === 200) {
          ElMessage.success("操作成功");
          handleCancel();
          emit("reload");
          console.log("编辑成功:", res);
        }
      } catch (error) {
        console.error("请求失败:", error);
      }
    } else {
      console.log("表单验证失败");
      // 添加详细验证错误输出
      const fields = formRef.value?.getFieldsError();
      console.log("验证错误详情:", fields);
    }
  });
};
</script>

<style scoped lang="less"></style>
